﻿using QuanLyGiaoVuDAL.DTO;
using QuanLyGiaoVuService.CommandServices;
using QuanLyGiaoVuService.CommonServices;
using QuanLyGiaoVuService.Domain;
using QuanLyGiaoVuService.ReportServices;
using QuanLyGiaoVuService.Utilities;
using QuanLyGiaoVuUI.Extensions.ExtendedAttributes;
using QuanLyGiaoVuUI.Extensions.Utilities;
using QuanLyGiaoVuUI.Models.DangKyGioDay;
using QuanLyGiaoVuUI.Models.XepLich;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace QuanLyGiaoVuUI.Controllers
{
    public class XepLichController : Controller
    {
        private IDangKyGioDayReportService _dangKyGioDayReportService;
        private IDangKyGioDayCommandService _dangKyGioDayCommandService;
        private ILopMonHocCommandService _lopMonHocCommandService;
        private ILopMonHocReportService _lopMonHocReportService;
        private IThamSoService _thamSoService;
        private IXepLichService _xepLichService;
        private IExcelService _excelService;
        private IFileService _fileService;
        private ITietHocService _tietHocService;
        private IXepLich2Service _xepLich2Service;
        private ITaiLieuReportService _taiLieuReportService;
        private IThongBaoCommandService _thongBaoCommandService;

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public XepLichController(IDangKyGioDayCommandService dangKyGioDayCommandService, 
            IDangKyGioDayReportService dangKyGioDayReportService, 
            IThamSoService thamSoService, 
            IXepLichService xepLichService, 
            ILopMonHocCommandService lopMonHocCommandService,
            ILopMonHocReportService lopMonHocReportService,
            IExcelService excelService,
            IFileService fileService,
            ITietHocService tietHocService,
            IXepLich2Service xepLich2Service,
            ITaiLieuReportService taiLieuService,
            IThongBaoCommandService thongBaoCommandService)
        {
            _dangKyGioDayCommandService = dangKyGioDayCommandService;
            _dangKyGioDayReportService = dangKyGioDayReportService;
            _thamSoService = thamSoService;
            _xepLichService = xepLichService;
            _lopMonHocCommandService = lopMonHocCommandService;
            _lopMonHocReportService = lopMonHocReportService;
            _excelService = excelService;
            _fileService = fileService;
            _tietHocService = tietHocService;
            _xepLich2Service = xepLich2Service;
            _taiLieuReportService = taiLieuService;
            _thongBaoCommandService = thongBaoCommandService;
        }

        [GiangVienAuthorize(ChiGiaoVu = true)]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult XepLich()
        {
            Guid hocKyHienTai;
            Guid.TryParse(_thamSoService.GetThamSo("HocKyHienTai"), out hocKyHienTai);
            List<DangKyGioDayViewModel> dangKyGioDayList = new List<DangKyGioDayViewModel>();
            List<DangKyGioDayViewModel> dangKyGioDayHuyList = new List<DangKyGioDayViewModel>();
            if (hocKyHienTai != Guid.Empty)
            {
                dangKyGioDayList = DangKyGioDayViewModel.FromDangKyGioDayDTOList(_dangKyGioDayReportService.GetAllThongTinDangKyGioDay(null, null, null, null, null, hocKyHienTai)).ToList();
                foreach (DangKyGioDayViewModel viewModel in dangKyGioDayList)
                {
                    viewModel.ThuTuTrongTuan = _tietHocService.GetThuTuTietTrongTuan(viewModel.Thu, viewModel.TietDauDTO.TietThu);
                    if (viewModel.Huy == true)
                        dangKyGioDayHuyList.Add(viewModel);
                }
                foreach (DangKyGioDayViewModel huy in dangKyGioDayHuyList)
                {
                    dangKyGioDayList.Remove(huy);
                }
            }
            var dsKetQua = _dangKyGioDayReportService.SapXepDanhSachDangKyGioDay(DangKyGioDayViewModel.ToDangKyGioDayDTOList(dangKyGioDayList));
            return View(DangKyGioDayViewModel.FromDangKyGioDayDTOList(dsKetQua));
        }

        [HttpPost]
        public JsonResult XepLichTuDong()
        {
            Guid hocKyHienTai;
            Guid.TryParse(_thamSoService.GetThamSo("HocKyHienTai"), out hocKyHienTai);
            IEnumerable<DangKyGioDayDTO> danhSachDangKyGioDayTheoHocKy = _dangKyGioDayReportService.GetAllThongTinDangKyGioDay(null, null, null, null,null, hocKyHienTai).Where(dk => dk.Huy == false);
            TimeBoard ketqua = _xepLichService.XepLich(danhSachDangKyGioDayTheoHocKy);
            XepLichItemObject[] danhSachLopDuocXepLich = ketqua.XepLichItemList.FindAll(item => item.DuocChon == true).ToArray();
            string[] idArray = ketqua.LayDanhSachMaLopChuaXet().Select(guid => guid.ToString()).ToArray();
            string idStringList = string.Join(",", idArray);
            LopMonHocDTO[] danhSachLopChuaDuocXepLich = _lopMonHocReportService.GetLopMonHocByIdList(idStringList).ToArray();
            var JSonResult = new
            {
                DanhSachLopXepThanhCong = danhSachLopDuocXepLich.OrderBy(item => item.ThuTu) ,
                DanhSachLopChuaXepLich = danhSachLopChuaDuocXepLich,
                Success = danhSachLopChuaDuocXepLich.Count() == 0
            };
            return Json(JSonResult);
        }

        [HttpPost]
        public JsonResult LuuKetQua(String[] danhSachMaDangKyGioDay)
        {
            object json;
            try
            {
                if (danhSachMaDangKyGioDay != null)
                {
                    var danhSachDangKy = string.Join(",", danhSachMaDangKyGioDay);
                    string message = _dangKyGioDayReportService.KiemTraSapXep(danhSachDangKy);
                    if (String.IsNullOrEmpty(message))
                    {
                        for (int index = 0; index < danhSachMaDangKyGioDay.Length; index++)
                        {
                            Guid maDK;
                            if (Guid.TryParse(danhSachMaDangKyGioDay[index], out maDK))
                                _lopMonHocCommandService.XacNhanDangKy(maDK);
                        }
                    }
                    else
                        throw new Exception(message);
                }
                json = new
                {
                    success = true
                };
            }
            catch (Exception exception)
            {
                json = new
                {
                    success = false,
                    message = exception.Message
                };
            }
            return Json(json);
        }

        [HttpGet]
        public ActionResult XepLichContextMenu()
        {
            return View();
        }

        [HttpGet]
        public ActionResult HuyDangKyDialog()
        {
            return View();
        }

        [HttpPost]
        public JsonResult XacNhanHuy(Guid maDangKyHuy, String ghiChu)
        {
            object jsonData;
            try
            {
                _dangKyGioDayCommandService.HuyThongTinDangKyGioday(maDangKyHuy, ghiChu);
                jsonData = new
                {
                    success = true,
                    message = "Hủy thành công."
                };
            }
            catch (Exception exception)
            {
                jsonData = new
                {
                    success= false,
                    message=exception.Message
                };
            }
            return Json(jsonData);
        }

        [HttpGet]
        [GiangVienAuthorize(ChiGiaoVu = true)]
        public ActionResult XuatLich()
        {
            XuatLichViewModel viewModel = new XuatLichViewModel();
            viewModel.danhSachFileMau = _taiLieuReportService.GetAllTaiLieu(UserUtility.GetCurrentUser().MaNguoiDung, true, _thamSoService.GetGuid(ThamSoConstantUtility.MALOAIFILEMAU), null, null);
            return View("XuatFileExcel",viewModel);
        }

        [HttpPost]
        public ActionResult XuatFile(Guid? FileMau)
        {
            Stream fileStream;
            string fileName, contentType;
            if (!FileMau.HasValue)
                throw new Exception("Chưa chọn file mẫu.");
            bool readSuccess = _fileService.GetFileStreamById((Guid)FileMau, out fileStream, out fileName, out contentType);
            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = new byte[4096];
            while (true)
            {
                int readDataCount = fileStream.Read(buffer, 0, buffer.Length);
                if (readDataCount <= 0)
                    break;
                memoryStream.Write(buffer, 0, readDataCount);
            }
            fileStream.Close();

            Guid maHocKyHienTai = Guid.Parse(_thamSoService.GetThamSo("HocKyHienTai"));
            var dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => lop.MaTietDau != null && lop.MaTietSau != null);
            List<DangKyHocPhanTemplateModel> templateModelList = new List<DangKyHocPhanTemplateModel>();
            int stt = 1;
            foreach (var lopMonHocDTO in dsLopMonHoc)
            {
                DangKyHocPhanTemplateModel model = _lopMonHocReportService.LayThongTinDangKyHocPhanCuaLop(lopMonHocDTO.LopMonHocId);
                model.STT = stt++;
                templateModelList.Add(model);
            }
            var tokenList = _excelService.GetAllTokenFromTemplate("DangKyHocPhanTemplateToken");

            uint startRowIndex;
            memoryStream.Seek(0, SeekOrigin.Begin);
            var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
            _excelService.ExportToExcelWithTemplate<DangKyHocPhanTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return File(memoryStream, contentType, fileName);
        }

        [HttpPost]
        public ActionResult XuatFileDefault()
        {
            Stream fileStream;
            string fileName, contentType;
            var taiLieu = _taiLieuReportService.GetTaiLieuById(_thamSoService.GetGuid(ThamSoConstantUtility.MATAILIEUDANHSACHLOP));
            Guid fileId;
            if (taiLieu == null)
                throw new Exception("Chưa chọn file mẫu.");
            fileId = taiLieu.MaTapTin;
            bool readSuccess = _fileService.GetFileStreamById(fileId, out fileStream, out fileName, out contentType);
            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = new byte[4096];
            while (true)
            {
                int readDataCount = fileStream.Read(buffer, 0, buffer.Length);
                if (readDataCount <= 0)
                    break;
                memoryStream.Write(buffer, 0, readDataCount);
            }
            fileStream.Close();

            Guid maHocKyHienTai = Guid.Parse(_thamSoService.GetThamSo(ThamSoConstantUtility.HOCKYHIENTAI));
            var dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => lop.MaTietDau != null && lop.MaTietSau != null);
            List<DangKyHocPhanTemplateModel> templateModelList = new List<DangKyHocPhanTemplateModel>();
            int stt = 1;
            foreach (var lopMonHocDTO in dsLopMonHoc)
            {
                DangKyHocPhanTemplateModel model = _lopMonHocReportService.LayThongTinDangKyHocPhanCuaLop(lopMonHocDTO.LopMonHocId);
                model.STT = stt++;
                templateModelList.Add(model);
            }
            var tokenList = _excelService.GetAllTokenFromTemplate("DangKyHocPhanTemplateToken");

            uint startRowIndex;
            memoryStream.Seek(0, SeekOrigin.Begin);
            var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
            _excelService.ExportToExcelWithTemplate<DangKyHocPhanTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return File(memoryStream, contentType, fileName);
        }

        //[HttpPost]
        //public ActionResult XuatFile()
        //{
        //    HttpPostedFileBase uploadTemplate = null;
        //    foreach (string file in Request.Files)
        //    {
        //        uploadTemplate = Request.Files[file];
        //    }

        //    if (uploadTemplate != null)
        //    {
        //        Guid maHocKyHienTai = Guid.Parse(_thamSoService.GetThamSo("HocKyHienTai"));
        //        var dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => lop.MaTietDau != null && lop.MaTietSau != null);
        //        List<DangKyHocPhanTemplateModel> templateModelList = new List<DangKyHocPhanTemplateModel>();
        //        int stt = 1;
        //        foreach (var lopMonHocDTO in dsLopMonHoc)
        //        {
        //            DangKyHocPhanTemplateModel model = _lopMonHocReportService.LayThongTinDangKyHocPhanCuaLop(lopMonHocDTO.LopMonHocId);
        //            model.STT = stt++;
        //            templateModelList.Add(model);
        //        }
        //        var tokenList = _excelService.GetAllTokenFromTemplate("DangKyHocPhanTemplateToken");
        //        MemoryStream memoryStream = new MemoryStream();

        //        byte[] buffer = new byte[4096];
        //        while (true)
        //        {
        //            int read = uploadTemplate.InputStream.Read(buffer, 0, buffer.Length);
        //            if (read <= 0)
        //            {
        //                break;
        //            }
        //            memoryStream.Write(buffer, 0, read);
        //        }
        //        uploadTemplate.InputStream.Close();
        //        uint startRowIndex;
        //        memoryStream.Seek(0, SeekOrigin.Begin);
        //        var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
        //        _excelService.ExportToExcelWithTemplate<DangKyHocPhanTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
        //        memoryStream.Seek(0, SeekOrigin.Begin);
        //        return File(memoryStream, uploadTemplate.ContentType, uploadTemplate.FileName);
        //    }
        //    return View();
        //}

        [HttpGet]
        [GiangVienAuthorize(ChiGiaoVu = true)]
        public ActionResult XepLichGiangDay()
        {
            Guid maHocKyTiepTheo = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYTIEPTHEO);
            var danhSachLop = (_xepLich2Service.TaoDanhSachKhaNang(maHocKyTiepTheo));
            return View(danhSachLop);
        }

        [HttpPost]
        [GiangVienAuthorize(ChiGiaoVu = true, ReturnJson=true)]
        public JsonResult XepLich2()
        {
            try
            {
                Guid maHocKyTiepTheo = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYTIEPTHEO);
                List<LopMonHocDTO> dsKhongTheXep;
                List<GiangVienDTO> dsGiangVien;
                List<LopMonHocDTO> dsXepThanhCong = _xepLich2Service.XepLich(maHocKyTiepTheo, out dsKhongTheXep, out dsGiangVien).ToList();
                return Json(new
                {
                    success = true,
                    dsXepThanhCong = dsXepThanhCong,
                    dsKhongTheXep = dsKhongTheXep,
                    dsGiangVienChuaDKLich = dsGiangVien
                });
            }
            catch (Exception exception)
            {
                log.Error(exception.Message, exception);
                return Json(new { 
                    success = false,
                    message = "Xếp lịch không thành công."
                });
            }
        }

        [HttpPost]
        [GiangVienAuthorize(ChiGiaoVu=true, ReturnJson=true)]
        public JsonResult GuiThongBaoGiangVien(string maLops)
        {
            try
            {
                var danhSachLop = _lopMonHocReportService.GetLopMonHocByIdList(maLops);
                var danhSachGiangVien = danhSachLop.Select(lop => lop.GiangVien1);
                string nguoiNhanIds = string.Empty;
                if (danhSachGiangVien != null)
                {
                    foreach (var giangVien in danhSachGiangVien)
                    {
                        nguoiNhanIds += giangVien.ID.ToString() + ",";
                    }
                    nguoiNhanIds = nguoiNhanIds.TrimEnd(',');
                    ThongBaoDTO thongBaoDTO = new ThongBaoDTO();
                    thongBaoDTO.NguoiGuiId = UserUtility.GetCurrentUser().MaNguoiDung;
                    thongBaoDTO.NgayGuiThongBao = DateTime.Now;
                    thongBaoDTO.TieuDeThongBao = "[Gửi tự động] Thông báo xếp lịch";
                    thongBaoDTO.NoiDungThongBao = "Kính chào quý thầy (cô), \r\n";
                    thongBaoDTO.NoiDungThongBao += "Sau khi tiến hành xếp lịch cho học kỳ tới, hệ thống không thể xếp lịch cho các lớp sau: \r\n";
                    foreach (var lop in danhSachLop)
                    {
                        thongBaoDTO.NoiDungThongBao += lop.MaLopVaTenMonHoc + "(" + lop.GiangVien1.GetTenVaHocVi() + ") \n\r";
                    }
                    thongBaoDTO.NoiDungThongBao += "Đề nghị quý thầy (cô) sắp xếp thêm lịch rãnh để việc xếp lịch được thuận lợi.\n\r";
                    thongBaoDTO.NoiDungThongBao += "Trân trọng.";
                    _thongBaoCommandService.InsertThongBao(thongBaoDTO, nguoiNhanIds);
                }

                return Json(new {
                    success = true
                });
            }
            catch (Exception exception)
            {
                return Json(new { 
                    success = false
                });
            }
        }

        [HttpPost]
        [GiangVienAuthorize(ChiGiaoVu = true, ReturnJson = true)]
        public JsonResult CellHtml(String lopMonHocIds, String khaNangs)
        {
            try
            {
                string html = _xepLich2Service.BuildHtml(lopMonHocIds, khaNangs);
                return Json(new {
                    success = true,
                    htmlContent = html
                });
            }
            catch (Exception exception)
            {
                return Json(new {
                    success = false,
                    message = exception.Message
                });
            }
        }

        [HttpPost]
        [GiangVienAuthorize(ChiGiaoVu = true, ReturnJson = true)]
        public JsonResult LuuKetQuaXepLich(String lopMonHocIds, String khaNangs)
        {
            try
            {
                _xepLich2Service.LuuKetQua(lopMonHocIds, khaNangs);
                return Json(new
                {
                    success = true
                });
            }
            catch (Exception exception)
            {
                return Json(new
                {
                    success = false,
                    message = exception.Message
                });
            }
        }
    }
}
